﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Http;

namespace TowerCraneMonitorClient.NetClient.HttpClient
{
    class NetHttpClient
    {
        const int maxResponseContentBufferSize = 1024;
        const string contentType = "application/json";
        static readonly System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();

        public event EventHandler<string> OnSend;
        public event EventHandler<ResponseRecord> OnResponse;

        static NetHttpClient() => client.MaxResponseContentBufferSize = maxResponseContentBufferSize;

        public async void Send(string url, string json)
        {
            try
            {
                OnSend?.Invoke(this, json);

                HttpResponseMessage response;
                using (var content = GetContent(json)) response = await client.PostAsync(url, content);
                response.EnsureSuccessStatusCode();

                string responseBodyAsText = await response.Content.ReadAsStringAsync();
                var result = new ResponseRecord
                {
                    Status = $"{response.StatusCode} {response.ReasonPhrase}",
                    Json = responseBodyAsText
                };
                OnResponse?.Invoke(this, result);
            }
            catch (HttpRequestException hre)
            {
                Console.WriteLine($"HttpRequestException: <{hre.ToString()}>");
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
            {
                Console.WriteLine($"Exception: <{ex.ToString()}>");
            }
#pragma warning restore CA1031 // Do not catch general exception types
        }

        HttpContent GetContent(string json)
        {
            var helper = new ClientHelper();
            var content = new StringContent(json);
            content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
            content.Headers.Add("keyId", helper.KeyId);
            content.Headers.Add("ts", helper.TimeStamp.ToString());
            content.Headers.Add("rCode", helper.RandomCode);
            content.Headers.Add("signature", helper.Signature);

            string headers = content.Headers.Select(p => new { key = p.Key, value = p.Value.Aggregate("", (x, y) => x + $";{y}") })
                .Select(p => $"{p.key}:{p.value}")
                .Aggregate("", (p, s) => p + " " + s);
            return content;
        }

        public class ResponseRecord
        {
            public string Status { get; set; }
            public string Json { get; set; }
        }
    }
}
